package com.ruoyi.distributionPoster.util;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.ruoyi.common.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.ByteArrayOutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.UUID;

/**
 * 二维码生成工具类
 *
 * @author ruoyi
 * @date 2025-11-21
 */
@Component
public class QRCodeGenerator {

    private static final Logger log = LoggerFactory.getLogger(QRCodeGenerator.class);

    @Value("${qrcode.storage.path:./qrcodes}")
    private String qrCodeStoragePath;

    @Value("${qrcode.base-url:http://localhost:8080/qrcodes}")
    private String qrCodeBaseUrl;

    /**
     * 生成二维码并保存到文件系统
     *
     * @param content 二维码内容
     * @param width 图片宽度
     * @param height 图片高度
     * @return 二维码图片URL
     */
    public String generateQRCodeImage(String content, int width, int height) {
        try {
            // 创建二维码写入器
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height);

            // 生成唯一文件名
            String fileName = UUID.randomUUID().toString() + ".png";
            Path filePath = Paths.get(qrCodeStoragePath, fileName);

            // 确保目录存在
            Files.createDirectories(filePath.getParent());

            // 写入文件
            MatrixToImageWriter.writeToPath(bitMatrix, "PNG", filePath);

            // 返回可访问的URL
            return qrCodeBaseUrl + "/" + fileName;

        } catch (Exception e) {
            log.error("生成二维码失败", e);
            throw new ServiceException("二维码生成失败: " + e.getMessage());
        }
    }

    /**
     * 生成二维码的Base64编码字符串（适用于小图片）
     *
     * @param content 二维码内容
     * @param width 图片宽度
     * @param height 图片高度
     * @return Base64编码的图片数据
     */
    public String generateQRCodeBase64(String content, int width, int height) {
        try {
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height);

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(bitMatrix, "PNG", outputStream);

            byte[] imageBytes = outputStream.toByteArray();
            return "data:image/png;base64," + Base64.getEncoder().encodeToString(imageBytes);

        } catch (Exception e) {
            log.error("生成二维码Base64失败", e);
            throw new ServiceException("二维码生成失败: " + e.getMessage());
        }
    }

    /**
     * 生成二维码字节数组，可用于上传到远程服务器
     *
     * @param content 二维码内容
     * @param width 图片宽度
     * @param height 图片高度
     * @return 二维码图片字节数组
     */
    public byte[] generateQRCodeBytes(String content, int width, int height) {
        try {
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height);

            ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
            MatrixToImageWriter.writeToStream(bitMatrix, "PNG", outputStream);

            return outputStream.toByteArray();
        } catch (Exception e) {
            log.error("生成二维码字节数据失败", e);
            throw new ServiceException("二维码生成失败: " + e.getMessage());
        }
    }

    /**
     * 检查存储目录是否存在，不存在则创建
     */
    public void ensureStorageDirectoryExists() {
        try {
            Path path = Paths.get(qrCodeStoragePath);
            if (!Files.exists(path)) {
                Files.createDirectories(path);
                log.info("创建二维码存储目录: {}", qrCodeStoragePath);
            }
        } catch (Exception e) {
            log.error("创建二维码存储目录失败", e);
        }
    }
}